package com.xinyue.ext.reader.dao;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;

import com.xinyue.ext.data.FinderData;
import com.xinyue.ext.exception.FinderException;
import com.xinyue.ext.reader.ParamHolder;
import com.xinyue.ext.util.StringUtil;

public class HqlProcess extends DaoContext{
	//私有构造器
	private HqlProcess() {
	}
	//内部类
	private static class SingletonHolder{
        private static HqlProcess instance = new HqlProcess();  
    }
	/**
	 * 获得对象实例
	 */
	public static HqlProcess getInstance(ParamHolder holder) {
		DaoContext.holder = holder;
		return SingletonHolder.instance;
	}
	

	/**
	 * 读取hql标签数据
	 * param finder finder标签
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void read(Element finder) throws FinderException {
		List<Element> hqs = finder.elements(hql_);
		
		//存在hql标签
		if(hqs != null && hqs.size() > 0) {
			List<FinderData> finders = new ArrayList<FinderData>();
			
			for (Element e: hqs) {
				FinderData find = commonRead(e);
				//返回值、强制类型转换、是否单个结果集处理
				returnType(e.attributeValue(returnType_), find, hql_type);
				//入参、paramSetter及hql语句处理
				hqlProcess(e, find);
				
				finders.add(find);
			}
			
			holder.getEntity().getDao().setHqls(finders);;
		}
	}

	
	/**
	 * 对SQL语句进行预处理
	 * @throws FinderException
	 */
	@SuppressWarnings("unchecked")
	private void hqlProcess(Element e, FinderData find) throws FinderException {
		List<Element> params = e.elements(query_param_);
		if(params != null && params.size() > 0) {
			String param = "";
			List<String> setter = new ArrayList<String>();
			
			for (Element p: params) {
				String name = p.attributeValue(name_);
				if(StringUtil.isNull(name)) {
					throw new FinderException("query-param标签没有定义name属性或者其值为空", holder.getException());
				}
				
				String type = p.attributeValue(type_);
				if(StringUtil.isNull(type)) {
					throw new FinderException("query-param标签没有定义type属性或者其值为空", holder.getException());
				}
				//验证参数是否合法并返回setter
				String set = setterOperate(name, type);
				if(set == null) {
					throw new FinderException("query-param标签type属性值不合法:" + type, holder.getException());
				}
				setter.add(set);
				
				param += type + " " + name + ", ";
			}
			
			find.setParams(param.substring(0, param.length() - 2));
			find.setParamSetter(setter);
		}
		
		Element hql = e.element(hql_state_);
		find.setState(hql.getTextTrim());
	}
}
